package org.jeecg.modules.pay.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.thirdapp.ThirdAppConfig;
import org.jeecg.config.thirdapp.ThirdAppTypeItemVo;
import org.jeecg.modules.pay.beans.beanAbc.ChargeBillRequest;
import org.jeecg.modules.pay.beans.beanAbc.ChargeBillResponse;
import org.jeecg.modules.pay.beans.beanAbc.QueryBillRequest;
import org.jeecg.modules.pay.beans.beanAbc.QueryBillResponse;
import org.jeecg.modules.pay.service.IBillReceiveService;
import org.jeecg.modules.pay.utils.HttpClientUtils;
import org.jeecg.modules.pay.utils.SignAndVerificationForAbc;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Api(tags="第三方查询账单")
@RestController
@RequestMapping("/abc/bill")
@Slf4j

public class BillReceiveController {
   @Resource(name = "billReceiveAbcService")
   private IBillReceiveService billReceiveAbcService;
   @Autowired
   private ThirdAppConfig thirdAppConfig;
   @Autowired
   private SignAndVerificationForAbc signAndVerificationForAbc;

   @AutoLog(value = "欠费账单")
   @ApiOperation(value="欠费账单", notes="欠费账单")
   @PostMapping(value = "/getArrearsBill")
   @ResponseBody
   public void getArrearsBill(String queryRequest,HttpServletRequest request, HttpServletResponse httpResponse) {
       log.info("进入QueryBillController账单查询接口--------(金额规则为0的)-------");
       String responseJson = null;
       try {
           //接收报文request返回截取并返回requsetBody和使用base64解析后的requsetBody
           Map<String,String> requestMap= signAndVerificationForAbc.requestBodyOfBase64(request);
           //使用base64解析完成后的requsetBody
           String requsetBodyOfDecoded=requestMap.get("requsetBodyOfDecoded");
           QueryBillRequest queryBillRequest = JSON.parseObject(requsetBodyOfDecoded,new TypeReference<QueryBillRequest>() {});
           //交易编号
           //String traceNo = queryBillRequest.getMessage().getInfo().getTraceNo();
           QueryBillRequest.Message.Info reqInfo = queryBillRequest.getMessage().getInfo();
           //第三方环境信息
//           ThirdAppTypeItemVo payAbcItem = thirdAppConfig.getPayAbc();

           //返回给缴费中心的响应
           QueryBillResponse response = new QueryBillResponse(queryBillRequest);
           QueryBillResponse.Message respMessage = response.getMessage();
           QueryBillResponse.Message.Head respHead = response.getMessage().getHead();
           QueryBillResponse.Message.Info respInfo=null;
           //欠费账单Obj
           JSONObject billObj=new JSONObject();
           if(null == reqInfo || oConvertUtils.isEmpty(reqInfo.getInput1())){
               //测试
               billObj.put("code","JH02");
               billObj.put("msg","缴费账号不能为空");
           }else{
               //if("8022030".equals(reqInfo.getInput1())){
                   billObj= billReceiveAbcService.queryBill(requestMap, reqInfo, response.getMessage().getInfo());
               //}
           }
           if(null != billObj && "0000".equals(billObj.getString("code"))){
               respInfo=(QueryBillResponse.Message.Info)billObj.get("bill");
               respHead.setReturnCode("0000");
               respHead.setReturnMessage("账单查询成功，返回成功标志");
           }else{
               respHead.setReturnCode(billObj.getString("code"));
               respHead.setReturnMessage(billObj.getString("msg"));
           }

           if(null == respInfo){
               respHead.setReturnCode("JH02");
               respHead.setReturnMessage("查询无记录，请检查输入是否有误");
           }

           respHead.setTransFlag("02");
           respHead.setTimeStamp(DateUtils.getDate("YYYYMMDDHHMMSSSSS"));
           respMessage.setInfo(respInfo);
           respMessage.setHead(respHead);
           response.setMessage(respMessage);
           responseJson = JSON.toJSONString(response);
           // 加签名
           String signatrue = signAndVerificationForAbc.signWhithsha1withrsa(thirdAppConfig.getPayAbc(),responseJson);
           //logger.info("signatrue" + responseJson);
           System.out.println("responseJson打印结果是（responseJson加密前）:" + responseJson);
           responseJson = signatrue + "||"
                   + new String(Base64.encodeBase64(responseJson.getBytes("utf-8")));
//           System.out.println("responseJson打印结果是（responseJson加密后）:" + responseJson);
           httpResponse.setCharacterEncoding("utf-8");
           httpResponse.setContentType("text/plain");
           httpResponse.getWriter().write(responseJson);
       } catch (Exception e) {
           e.printStackTrace();
       }
   }


    /**
     * 接收账单缴费（销账）接口
     *
     * @param
     * @return
     */
    @RequestMapping(value = "/getRequest4Sale", method = RequestMethod.POST)
    @ResponseBody
    public void getRequest4Sale(String queryRequest
            ,HttpServletRequest request, HttpServletResponse httpResponse) {
        String responseJson = null;
        try {
            // 接收报文
            String requestContent = HttpClientUtils.getRequestBody(request).trim();
            // log.info("-----ChargeBillController------------收到的报文：{}", requestContent);

            String signatureString = requestContent.substring(0,requestContent.indexOf("||"));
            // log.info("-----ChargeBillController------------截取报文的signatureString:", signatureString);
            String requestBody = requestContent.substring(signatureString.length() + 2);
            // log.info("-----ChargeBillController------------截取报文的requestBody:", requestBody);
            //如果有双引号，则截取双引号内requestBody的内容
            Pattern p= Pattern.compile("\"");
            Matcher m=p.matcher(requestBody);
            while(m.find()){
                requestBody=requestBody.replace(m.group(), "");
                // log.info("-----ChargeBillController------如果有双引号，则截取后的requestBody:", requestBody);
            }
            //requestBody是base64加密后的数据，需解析出来
            String requset = new String(com.alibaba.fastjson.util.Base64.decodeFast(requestBody));
//            log.info("-----ChargeBillController------------解析完成后的requestBody-------" + requset);
            ChargeBillRequest chargeBillRequest = JSON.parseObject(requset, new TypeReference<ChargeBillRequest>() {});
            //销账-请求消息体
            ChargeBillRequest.Message.Info questInfo = chargeBillRequest.getMessage().getInfo();
            //销账-请求消息头
            ChargeBillRequest.Message.Head questHead = chargeBillRequest.getMessage().getHead();
            /** 销账报文重发次数，通过resendTimes此字段识别销账报文是否为重发的，0表示首次、1表示重发一次，2表示重发2次，最多重发3次*/
            if(chargeBillRequest != null && "0".equals(questInfo.getResendTimes())){
                // 验签(验签是解析前的requestBody)
                Boolean verify_sign=signAndVerificationForAbc.read_cer_and_verify_sign(
                                thirdAppConfig.getPayAbc(),requestBody,signatureString);
                JSONObject jsonObject=new JSONObject();
                if(verify_sign){
                    //业务核销
                    jsonObject = billReceiveAbcService.saleBill(questHead,questInfo);
                }else{
                    jsonObject.put("code","JH02");
                    jsonObject.put("msg","验签失败");
                }
                ChargeBillResponse chargeBillResponse = new ChargeBillResponse(chargeBillRequest);
                ChargeBillResponse.Message respMessage = chargeBillResponse.getMessage();
                ChargeBillResponse.Message.Head respHead = chargeBillResponse.getMessage().getHead();
                ChargeBillResponse.Message.Info respInfo = chargeBillResponse.getMessage().getInfo();

                respHead.setTransFlag("02");
                respHead.setTimeStamp(DateUtils.formatDate("YYYYMMDDHHMMSSSSS"));
                // respHead.setChannel("MBNK");
                respHead.setChannel(questHead.getChannel());
                // respHead.setTranCode("chargeBill");
                respHead.setTransCode(questHead.getTransCode());
                respHead.setTransSeqNum(questHead.getTransSeqNum());
                //测试销账返回报文中，本来是销账成功的报文，但是不要送0000成功码   (JF190510134746710555这个流水号是在Demo的returnCode设置成null的时候产生的，流水状态为6；)
                respHead.setReturnCode(jsonObject.getString("code"));
                respHead.setReturnMessage(jsonObject.getString("msg"));
                String epayCode = questInfo.getEpayCode();
                String traceNo = questInfo.getTraceNo();
                String numOpenMerchantOrder = questInfo.getNumOpenMerchantOrder();
                respInfo.setNumOpenMerchantOrder(numOpenMerchantOrder);
                respInfo.setEpayCode(epayCode);
                respInfo.setTraceNo(traceNo);
                /**
                 * 返回码为0000时不读取本字段；
                 * 返回码非0000时，必须返回本标志位信息。返回true标志自动实时退款，返回false标志不做退款
                 */
                if (!"0000".equals(respHead.getReturnCode())) {
                    respInfo.setRefundFlag("true");
                }
                respMessage.setInfo(respInfo);
                respMessage.setHead(respHead);
                chargeBillResponse.setMessage(respMessage);
                responseJson = JSON.toJSONString(chargeBillResponse);
                //加签名
                String signatrue = signAndVerificationForAbc.signWhithsha1withrsa(thirdAppConfig.getPayAbc(),responseJson);
                log.info("-----ChargeBillController------------responseJson打印结果是（responseJson加密前）:" + responseJson);
                responseJson = signatrue + "||"
                        + new String(Base64.encodeBase64(responseJson.getBytes("utf-8")));
//                log.info("-----ChargeBillController------------responseJson打印结果是（responseJson加密后）:" + responseJson);
                httpResponse.setCharacterEncoding("utf-8");
                httpResponse.setContentType("text/plain");
                httpResponse.getWriter().write(responseJson);
            }else{
                //销账报文重发次数，通过resendTimes此字段识别销账报文是否为重发的，0表示首次、1表示重发一次，2表示重发2次，最多重发3次
                //商户端要注意销账重复通知的情况，要进行订单唯一性处理

                // 验签(验签是解析前的requestBody)
                Boolean verify_sign=signAndVerificationForAbc.read_cer_and_verify_sign(thirdAppConfig.getPayAbc(),requestBody,signatureString);
                JSONObject jsonObject=new JSONObject();
                if(verify_sign){
                    //业务核销
                    jsonObject = billReceiveAbcService.saleBill(questHead,questInfo);
                }else{
                    jsonObject.put("code","JH02");
                    jsonObject.put("msg","验签失败");
                }
                ChargeBillResponse chargeBillResponse = new ChargeBillResponse(chargeBillRequest);
                ChargeBillResponse.Message respMessage = chargeBillResponse.getMessage();
                ChargeBillResponse.Message.Head respHead = chargeBillResponse.getMessage().getHead();
                ChargeBillResponse.Message.Info respInfo = chargeBillResponse.getMessage().getInfo();
                respHead.setTransFlag("02");
                respHead.setTimeStamp(DateUtils.formatDate("YYYYMMDDHHMMSSSSS"));
                // respHead.setChannel("MBNK");
                respHead.setChannel(chargeBillRequest.getMessage().getHead().getChannel());
                // respHead.setTranCode("chargeBill");
                respHead.setTransCode(chargeBillRequest.getMessage().getHead().getTransCode());
                respHead.setTransSeqNum(chargeBillRequest.getMessage().getHead().getTransSeqNum());
                // 销账报文重发次数，通过resendTimes此字段识别销账报文是否为重发的，0表示首次、1表示重发一次，2表示重发2次，最多重发3次
                // 商户端要注意销账重复通知的情况，要进行订单唯一性处理

                respHead.setReturnCode(jsonObject.getString("code"));
                respHead.setReturnMessage(jsonObject.getString("msg"));

                // if (chargeBillRequest != null
                //         && ((Integer.parseInt(chargeBillRequest.getMessage()
                //         .getInfo().getResendTimes()))) % 4 == 0) {
                //
                //     // respHead.setReturnCode("0000");
                //     // respHead.setReturnMessage("账单缴费成功");
                //     if (!"0000".equals(respHead.getReturnCode())) {
                //         respInfo.setRefundFlag("true");
                //     }
                // }else if(chargeBillRequest != null
                //         && ((Integer.parseInt(chargeBillRequest.getMessage()
                //         .getInfo().getResendTimes()))) % 4 ==1){
                //     respHead.setReturnCode("1111");
                //     respHead.setReturnMessage("账单缴费失敗");
                //     if (!"0000".equals(respHead.getReturnCode())) {
                //         respInfo.setRefundFlag("false");
                //     }
                // }else if(chargeBillRequest != null
                //         && ((Integer.parseInt(chargeBillRequest.getMessage()
                //         .getInfo().getResendTimes()))) % 4 ==2){
                //     respHead.setReturnCode("1111");
                //     respHead.setReturnMessage("账单缴费失敗");
                //     if (!"0000".equals(respHead.getReturnCode())) {
                //         respInfo.setRefundFlag("true");
                //     }
                // }else if(chargeBillRequest != null
                //         && ((Integer.parseInt(chargeBillRequest.getMessage()
                //         .getInfo().getResendTimes()))) % 4 == 3){
                //     respHead.setReturnCode("JH01");
                //     respHead.setReturnMessage("账单缴费失敗");
                //     if (!"0000".equals(respHead.getReturnCode())) {
                //         respInfo.setRefundFlag("");
                //     }
                // }

                String epayCode = questInfo.getEpayCode();
                String traceNo = questInfo.getTraceNo();
                String numOpenMerchantOrder = questInfo.getNumOpenMerchantOrder();
                respInfo.setNumOpenMerchantOrder(numOpenMerchantOrder);
                respInfo.setEpayCode(epayCode);
                respInfo.setTraceNo(traceNo);

                respMessage.setInfo(respInfo);
                respMessage.setHead(respHead);
                chargeBillResponse.setMessage(respMessage);
                responseJson = JSON.toJSONString(chargeBillResponse);
                //加签名
                String signatrue = signAndVerificationForAbc.signWhithsha1withrsa(thirdAppConfig.getPayAbc(),responseJson);
                log.info("-----ChargeBillController------------responseJson打印结果是（responseJson加密前）:" + responseJson);
                responseJson = signatrue + "||"
                        + new String(Base64.encodeBase64(responseJson.getBytes("utf-8")));
//                log.info("-----ChargeBillController------------responseJson打印结果是（responseJson加密后）:" + responseJson);
                httpResponse.setCharacterEncoding("utf-8");
                httpResponse.setContentType("text/plain");
                httpResponse.getWriter().write(responseJson);
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}
